﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using FD.FileSyncServer.Entities;

namespace FD.FileSyncServer.Network
{
    public class ConnectServer : IConnectServer
    {
        private Socket _socket;
        private ServEndPoint _endPoint;
        private List<Socket> _clients = new List<Socket>();

        public event EventHandler<ReceivedArgs> Received;

        public ConnectServer(ServEndPoint endPoint)
        {
            _endPoint = endPoint;
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        public void Listen()
        {
            _socket.Listen(_endPoint.MaxConnection);
            _socket.BeginAccept(AcceptSocket, _socket);

        }

        private void AcceptSocket(IAsyncResult ar)
        {
            if (ar.IsCompleted)
            {
                var socket = (Socket)ar.AsyncState;
                var client = socket.EndAccept(ar);
                _clients.Add(client);
                client.Send(Encoding.UTF8.GetBytes("Hello, my client."));
                var buffer = new byte[1024 * 1024];
                while (client.Connected)
                {
                    client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, Receive,
                        new DataParameter { Socket = client, Buffer = buffer });
                }

                _clients.Remove(client);
            }
        }

        private void Receive(IAsyncResult ar)
        {
            if (ar.IsCompleted)
            {
                var dp = (DataParameter)ar.AsyncState;
                var client = dp.Socket;
                int count = client.EndReceive(ar);
                var str = Encoding.UTF8.GetString(dp.Buffer);
                Console.WriteLine(str);
                Received?.Invoke(client, new ReceivedArgs(dp.Buffer, count));
                client.Send(Encoding.UTF8.GetBytes($"Thank for {str}."));
            }
        }

        public bool Send(string msg)
        {
            return Send(Encoding.UTF8.GetBytes(msg));
        }

        public bool Send(byte[] buffer)
        {
            int ret = _socket.Send(buffer, SocketFlags.None);
            return ret > 0;
        }

        //public byte[] Receive(IAsyncResult ar)
        //{
        //    throw new NotImplementedException();
        //}
    }
}
